// b07.v
// Verilog version, rewritten by Li Shen, Aug 2002
// Institute of Computing Technology, Chinese Academy of Sciences
// The original VHDL version is b07.vhd from Politecnico di Torino

module b07 (clock, reset, start, punti_retta);
input clock;
input reset;
input start;
output [7:0] punti_retta;
/////
wire clock;
wire reset;
wire start;
reg [7:0] punti_retta;
/////
parameter lung_mem=15;
parameter S_RESET=0, S_START=1, S_LOAD_X=2, S_UPDATE_MAR=3;
parameter S_LOAD_Y=4, S_CALC_RETTA=5, S_INCREMENTA=6;
reg [2:0] stato;
reg [7:0] cont,mar,x,y,t;
/////
function [7:0] mem;
input [3:0] addr;
begin
  case (addr)
   0:  mem=1;  1:  mem=255; 2:  mem=0;   3:  mem=0;
   4:  mem=0;  5:  mem=2;   6:  mem=0;   7:  mem=0;
   8:  mem=0;  9:  mem=2;   10: mem=255; 11: mem=5;
   12: mem=0;  13: mem=2;   14: mem=0;   15: mem=2;
  endcase
end
endfunction
/////
always @(posedge clock)
begin
    if (reset)
    begin
	stato = S_RESET;
	punti_retta <= 0;
	cont = 0;
	mar = 0;
	x = 0;
	y = 0;
	t = 0;
    end
    else
      case (stato)
      S_RESET:
        stato =S_START;
      S_START:
        if (start)
        begin
          cont = 0;
          mar = 0;
          stato = S_LOAD_X;
        end
        else
        begin
          stato = S_START;
          punti_retta <= 0;
        end
      S_LOAD_X:
      begin
        x = mem(mar);
        stato =S_UPDATE_MAR;
      end
      S_UPDATE_MAR:
      begin
        mar = (mar +1) & 15;
        t = (x & 127)+ (x & 127);
        stato = S_LOAD_Y;
      end
      S_LOAD_Y:
      begin
        y = mem(mar);
        x = (x & 127)+(t & 127);
        stato = S_CALC_RETTA;
      end
      S_CALC_RETTA:
      begin
        x = (x & 127)+(y & 127);
        stato = S_INCREMENTA;
      end
      S_INCREMENTA:
        if (mar!=lung_mem)
        begin
          if (x==2)
          begin
	    cont = cont +1;
            mar = (mar +1) & 15;
            stato = S_LOAD_X;
          end
          else
          begin
            mar = (mar +1) & 15;
            stato = S_LOAD_X;
          end
        end
        else
        begin
          if (!start)
          begin
            if (x==2)
            begin
              punti_retta <= cont +1;
              stato=S_START;
            end
            else
            begin
              punti_retta<=cont; 
              stato=S_START;
            end
          end
          else
            stato=S_INCREMENTA;
        end
      endcase
end
endmodule
